package com.dh.leetcode.k1;

import org.junit.Assert;
import org.junit.Test;

import java.util.Arrays;

/**
 * @ClassName: _1005_maximize_sum_of_array_after_k_negations
 * @Description: 1005. K 次取反后最大化的数组和
 * 给你一个整数数组 nums 和一个整数 k ，按以下方法修改该数组：
 * <p>
 * 选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。
 * 重复这个过程恰好 k 次。可以多次选择同一个下标 i 。
 * <p>
 * 以这种方式修改数组后，返回数组 可能的最大和 。
 * <p>
 * <p>
 * <p>
 * 示例 1：
 * <p>
 * 输入：nums = [4,2,3], k = 1
 * 输出：5
 * 解释：选择下标 1 ，nums 变为 [4,-2,3] 。
 * 示例 2：
 * <p>
 * 输入：nums = [3,-1,0,2], k = 3
 * 输出：6
 * 解释：选择下标 (1, 2, 2) ，nums 变为 [3,1,0,2] 。
 * 示例 3：
 * <p>
 * 输入：nums = [2,-3,-1,5,-4], k = 2
 * 输出：13
 * 解释：选择下标 (1, 4) ，nums 变为 [2,3,-1,5,4] 。
 * <p>
 * 提示：
 * <p>
 * 1 <= nums.length <= 104
 * -100 <= nums[i] <= 100
 * 1 <= k <= 104
 * <p>
 * https://leetcode-cn.com/problems/maximize-sum-of-array-after-k-negations/
 * @Author: shouzimu
 * @Date: 2021/12/3 8:57
 */
public class _1005_maximize_sum_of_array_after_k_negations {

    public int largestSumAfterKNegations(int[] nums, int k) {
        Arrays.sort(nums);
        int len = nums.length;
        int i = 0;
        int lessZeroCount = 0;
        for (; i < len - 1; i++) {
            if (nums[i + 1] > 0) {
                break;
            } else {
                lessZeroCount++;
            }
        }
        if (lessZeroCount == 0) {
            if (k % 2 == 1) {
                nums[0] = 0 - nums[0];
            }
        } else {
            int j = 0;
            for (; j < i && k > 0; j++) {
                nums[j] = 0 - nums[j];
                k--;
            }
            if (j == i && k > 0) {
                if (k % 2 == 1) {
                    nums[j] = 0 - nums[j];
                } else {
                    if (i + 1 < len) {
                        if (Math.abs(nums[j]) > Math.abs(nums[i + 1])) {
                            nums[j] = Math.abs(nums[j]);
                            nums[i + 1] = 0 - nums[i + 1];
                        }
                    }
                }
            }
        }
        int sum = 0;
        for (int j = 0; j < len; j++) {
            sum += nums[j];
        }
        return sum;
    }

    @Test
    public void largestSumAfterKNegationsTest() {
        Assert.assertEquals(53, largestSumAfterKNegations(new int[]{8, -7, -3, -9, 1, 9, -6, -9, 3}, 8));
        Assert.assertEquals(22, largestSumAfterKNegations(new int[]{-8, 3, -5, -3, -5, -2}, 6));
        Assert.assertEquals(5, largestSumAfterKNegations(new int[]{4, 2, 3}, 5));
        Assert.assertEquals(6, largestSumAfterKNegations(new int[]{3, -1, 0, 2}, 3));
        Assert.assertEquals(-6, largestSumAfterKNegations(new int[]{6}, 3));
        Assert.assertEquals(13, largestSumAfterKNegations(new int[]{2, -3, -1, 5, -4}, 2));
    }
}
